; 1.用循环显示A-Z，并记人看得清
;*由于dosbox默认CPU速度是3000 cycles，相当于3MIPS
;(Million Instructions Per Second)：单字长定点指令平均执行速度
;Million Instructions Per Second的缩写，每秒处理的百万级的机器语言指令数。
;这是衡量CPU速度的一个指标。像是一个Intel80386 电脑可以每秒处理3百万到5百万机器语言指令，即我们可以说80386是3到5MIPS的CPU。MIPS只是衡量CPU性能的指标。)
;所以在dosbox要将mov dx设置得低一些才能看到结果，我设成20h
;在xp虚拟机中，设置成5000h

assume cs:code,ss:stack

stack segment stack
	db 128 dup(0)
stack ends

data segment
	dw 0,0
data ends

code segment

	start:
	;mov ax,stack
	;mov ss,ax
	;mov sp,128
	
	mov ax,data
	mov ds,ax
	mov ax,0
	mov es,ax
	push es:[9*4]
	pop ds:[0]
	push es:[9*4+2]
	pop ds:[2] ;将原来的int 9 中断例程的入口地址，保存在ds:[0]和ds:[2]单元中
	
	cli
	mov word ptr es:[9*4],offset int9
	mov es:[9*4+2],cs ;在中断向量表中设置新的int 9 中断例程的入口地址（offset int9和cs）
	sti
	
	mov ax,0b800h
	mov es,ax
	mov ah,'a'
	s:
	mov es:[100*12+20*2],ah
	call delay
	inc ah
	cmp ah,'z'
	jna s
	
	mov ax,0
	mov es,ax
	push ds:[0]
	pop es:[9*4]
	push ds:[2]
	pop es:[9*4+2]
	
	
	mov ax,4c00h
	int 21h
	
	delay: ;延迟子程序 
	push ax
	push dx
	mov dx,20h ;在xp虚拟机中，设置成5000h
	mov ax,0
	s1:
	sub ax,1
	sbb dx,0
	cmp ax,0 
	jne s1
	cmp dx,0 
	jne s1 
	pop dx
	pop ax
	ret
	
	
	int9: ;新的int9中断例程
	push ax
	push bx
	push es
	
	in al,60h
	;----------------------此处开始是为了模拟 int 指令调用功能
	pushf
	pushf
	pop bx
	and bh,11111100b ;设置if,tf为零
	push bx
	popf
	call dword ptr ds:[0]
	;----------------------模拟int 指令调用功能结束 
	
	cmp al,22h ;检测是否按下变色键,22h是g
	jne int9ret ;若不是g，就跳转，程序返回
	
	mov ax,0b800h
	mov es,ax
	inc byte ptr es:[100*12+20*2+1]
	
	int9ret:
	pop es
	pop bx
	pop ax
	iret 
	
	
code ends
end start